<!doctype html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>xeokit Example</title>
    <link href="../css/pageStyle.css" rel="stylesheet"/>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.13.0/js/all.min.js"></script>
</head>
<body>
<input type="checkbox" id="info-button"/>
<label for="info-button" class="info-button"><i class="far fa-3x fa-question-circle"></i></label>
<canvas id="myCanvas"></canvas>
<div class="slideout-sidebar">
    <img class="info-icon" style="width:280px; padding-bottom:10px;" src="../../assets/images/bim_icon.png"/>
    <h1>XKTLoaderPlugin, Data Textures & Metadata</h1>
    <h2>Loading a BIM model from an XKT file into a data texture model representation</h2>
    <h3>Using IFC metadata to separate building storeys.</h3>
    <p>Loads an .xkt IFC model from the file system, then uses the model's metadata to reveal each
        building storey.</p>
    <p>Note that translation of objects requires the Viewer to be configured with <code>entityOffsetsEnabled</code> set
        <code>true</code>.
    </p>
    <h3>Stats</h3>
    <ul>
        <li>
            <div id="time">Loading JavaScript modules...</div>
        </li>
    </ul>
    <h3>Components Used</h3>
    <ul>
        <li>
            <a href="../../docs/class/src/viewer/Viewer.js~Viewer.html"
               target="_other">Viewer</a>
        </li>
        <li>
            <a href="../../docs/class/src/plugins/XKTLoaderPlugin/XKTLoaderPlugin.js~XKTLoaderPlugin.html"
               target="_other">XKTLoaderPlugin</a>
        </li>
        <li>
            <a href="../../docs/class/src/viewer/metadata/MetaScene.js~MetaScene.html"
               target="_other">MetaScene</a>
        </li>
    </ul>
    <h3>Tutorials</h3>
    <ul>
        <li>
            <a href="https://www.notion.so/xeokit/Compact-Model-Representation-using-Data-Textures-e8093ae372fa47bf9995c26dc24ccd53?pvs=4"
               target="_other">Compact Model Representation using Data Textures</a>
        </li>
    </ul>
    <h3>Assets</h3>
    <ul>
        <li>
            <a href="https://github.com/openBIMstandards/DataSetSchependomlaan"
               target="_other">Model source</a>
        </li>
    </ul>
</div>
</body>
<script type="module">

    //------------------------------------------------------------------------------------------------------------------
    // Import the modules we need for this example
    //------------------------------------------------------------------------------------------------------------------

    import {
        Viewer,
        XKTLoaderPlugin,
        math,
        VBOGeometry,
        buildGridGeometry,
        PhongMaterial,
        Mesh
    } from "../../dist/xeokit-sdk.min.es.js";

    //------------------------------------------------------------------------------------------------------------------
    // Create a Viewer, arrange the camera, tweak the x-ray material and  SAO
    //------------------------------------------------------------------------------------------------------------------

    const viewer = new Viewer({
        canvasId: "myCanvas",
        transparent: true,
        entityOffsetsEnabled: true, // <<----------------- Enable Entity#offset
        dtxEnabled: true
    });

    const cameraControl = viewer.cameraControl;
    const scene = viewer.scene;
    const sao = scene.sao;
    const camera = scene.camera;

    camera.eye = [-26.07, 52.94, 35.13];
    camera.look = [-6.81, -9.43, 7.75];
    camera.up = [0.50, 0.47, -0.72];

    camera.perspective.near = 0.1;
    camera.perspective.far = 5000.0;

    //------------------------------------------------------------------------------------------------------------------
    // Create a ground plane
    //------------------------------------------------------------------------------------------------------------------

    new Mesh(viewer.scene, {
        geometry: new VBOGeometry(viewer.scene, buildGridGeometry({
            size: 600,
            divisions: 100
        })),
        material: new PhongMaterial(viewer.scene, {
            color: [0.0, 0.0, 0.0],
            emissive: [0.4, 0.4, 0.4]
        }),
        position: [0, -1.6, 0],
        collidable: false
    });

    //------------------------------------------------------------------------------------------------------------------
    // Load building model
    //------------------------------------------------------------------------------------------------------------------

    const xktLoader = new XKTLoaderPlugin(viewer);

    const sceneModel = xktLoader.load({
        id: "myModel",
        src: "../../assets/models/xkt/v8/ifc/Schependomlaan.ifc.xkt",
        saoEnabled: true,
        edges: true,
        objectDefaults: { // This model has opaque windows / spaces; make them transparent
            "IfcPlate": {
                opacity: 0.3 // These are used as windows in this model - make transparent
            },
            "IfcWindow": {
                opacity: 0.4
            },
            "IfcSpace": {
                opacity: 0.4
            }
        }
    });

    const t0 = performance.now();

    document.getElementById("time").innerHTML = "Loading model...";

    //------------------------------------------------------------------------------------------------------------------
    // When model loaded, slide each building storey out and lay it on the ground plane
    //------------------------------------------------------------------------------------------------------------------

    sceneModel.on("loaded", function () {

        setTimeout(() => {

            const t1 = performance.now();
            document.getElementById("time").innerHTML = "Model loaded in " + Math.floor(t1 - t0) / 1000.0 + " seconds<br>Objects: " + sceneModel.numEntities;

            moveObject("0u4wgLe6n0ABVaiXyikbkA", [-25, -3, 0]);
            moveObject("0wPqxf9KX0nPDjgzD8mXwD", [-25, -6, 25]);
            moveObject("2Hyat1fsPEGfyYPyim12A1", [0, -9, 25]);
            moveObject("0oaSdYqubDuuJF4k9AqHjC", [0, -12, -25]);

        }, 500);
    });

    function moveObject(objectId, dir, done) {

        const metaObject = viewer.metaScene.metaObjects[objectId];
        if (!metaObject) {
            return;
        }

        const objectIds = viewer.metaScene.getObjectIDsInSubtree(objectId);
        const dmax = math.lenVec3(dir);
        let d = 0;

        const onTick = scene.on("tick", () => {
            d += 0.75;
            if (d > dmax) {
                scene.off(onTick);
                if (done) {
                    done();
                }
                return;
            }
            scene.setObjectsOffset(objectIds, math.mulVec3Scalar(dir, (d / dmax), []));
        });
    }

</script>
</html>